// 失败的作品，已废弃
(function (global) {
  // !!! need js env >=ES6
  // 判断是否支持ES6语法
  try {
    eval("(()=>Reflect.has(globalThis,'Promise'))()");
  } catch (error) {
    console.log(error);
    throw Error("当前JavaScript运行环境不支持ES6语法");
  }
  // core
  // 核心类Var
  function Var(...rest) {
    // no must new
    // 不用new关键字也能new实例
    if (!new.target) {
      return new Var(...rest);
    }
    // 私有方法
    // private function
    this.__set = (newValue) => {
      Reflect.defineProperty(this, "value", {
        value: newValue,
      });
    };
    this.__setProp = (prop, newValue) => {
      Reflect.defineProperty(this.value, prop, {
        value: newValue,
      });
    };
    // 构造函数参数
    // arguments
    const [value] = rest;
    // 对外暴露的属性和方法
    // expose
    this.typeString = Var.getTypeToString(value);
    // 数据源
    this.value = value;
    // 获取数据
    this.get = (defaultValue) => {
      return Var.isEqual(defaultValue, Var.Undefined)
        ? this.value
        : this.value || defaultValue;
    };
    // 设置数据
    this.set = (...setRest) => {
      switch (setRest.length) {
        case 1:
          {
            const [newValue] = setRest;
            if (Var.isEqual(this.typeString, Var.getTypeToString(newValue))) {
              this.__set(newValue);
            } else {
              throw Error("赋值类型不一致");
            }
          }
          break;
        case 2:
          {
            const [attr, newValue] = setRest;
            this.__setProp(attr, newValue);
          }
          break;
      }
      return this;
    };
    // 把值设置为空
    this.setNull = () => {
      this.__set(null);
      return this;
    };
    // 判断是否为空
    this.isEmpty = () => {
      return Var.isEqual(this.value, null);
    };
    // 判断是否相等
    this.isEqual = (...isEqualRest) => {
      return Var.isEqual(this.value, ...isEqualRest);
    };
    this.valueOf = this.get;
    // boolean专属
    switch (this.typeString) {
      case "[object Boolean]":
        {
          this.toggle = () => {
            this.__set(!this.value);
            return this;
          };
        }
        break;
    }
    // no writeable
    // 防止实例方法和属性被重写
    const exposeKeys = Reflect.ownKeys(this);
    Var.each(exposeKeys, (key) => {
      Reflect.defineProperty(this, key, {
        writable: false,
      });
    });
  }

  // static
  // 设置静态方法和数据
  const staticData = {
    Undefined: void 0,
    each(array, callback) {
      let i = 0;
      while (i < array.length) {
        if (callback(array[i], i++, array) === false) return false;
      }
      return true;
    },
    times(times, callback) {
      while (times-- > 0) {
        callback();
      }
    },
    getTypeToString(target) {
      return Object.prototype.toString.call(target);
    },
    isEqual(...isEqualRest) {
      if (isEqualRest.length < 2) return false;
      if (isEqualRest.length < 3) {
        const [first, second] = isEqualRest;
        return first === second;
      }
      const [first, ...list] = isEqualRest;
      return this.each(list, (item) => {
        return item === first;
      });
    },
    compose(...rest) {
      const args = [].slice.call(rest);
      return (x) => {
        return args.reduceRight((res, cb) => {
          return cb(res);
        }, x);
      };
    },
    pipe(...rest) {
      const args = [].slice.call(rest);
      return (x) => {
        return args.reduce((res, cb) => {
          return cb(res);
        }, x);
      };
    },
    joinBy(separator) {
      return (...rest) => rest.join(separator);
    },
    microTask(cb, that) {
      Promise.resolve().then(cb.bind(that));
    },
    uuid() {
      const s = [];
      const hexDigits = "0123456789abcdef";
      for (let i = 0; i < 36; i++) {
        s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
      }
      s[14] = "4"; // bits 12-15 of the time_hi_and_version field to 0010
      s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01
      s[8] = s[13] = s[18] = s[23] = "-";

      const uuid = s.join("");
      return uuid;
    },
  };
  Object.keys(staticData).forEach((key) => {
    const item = staticData[key];
    if (typeof item === "function") {
      Var[key] = staticData[key].bind(Var);
    } else {
      Var[key] = staticData[key];
    }
  });

  // global setting
  // 将Var防止与全局变量中并设置不可修改
  global.Var = Var;
  Reflect.defineProperty(global, "Var", {
    writable: false,
    configurable: false,
    enumerable: false,
  });
})(globalThis);
